/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 - 2008 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/

package com.genia.toolbox.web.gwt.basics.client.widget;

import java.util.Date;

import com.genia.toolbox.web.gwt.basics.client.CssNames;
import com.genia.toolbox.web.gwt.basics.client.listener.CustomDelegatingChangeListenerCollection;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;

/**
 * GWT widget to choose a time.
 */
public class TimeChooser
    extends Composite
    implements AbstractDateChooser
{

  /**
   * number of ms in a minute.
   */
  public static final long MS_BY_MINUTE = 1000l * 60;

  /**
   * number of ms in a hour.
   */
  public static final long MS_BY_HOUR = MS_BY_MINUTE * 60;

  /**
   * number of ms in a day.
   */
  private static final long MS_BY_DAY = MS_BY_HOUR * 24;

  /**
   * {@link ListBox} containing the choice of hours.
   */
  private final ListBox hoursListBox = new ListBox();

  /**
   * {@link ListBox} containing the choice of minutes.
   */
  private final ListBox minutesListBox = new ListBox();

  /**
   * the registered {@link ChangeListener}s.
   */
  private CustomDelegatingChangeListenerCollection changeListeners = new CustomDelegatingChangeListenerCollection(this);



  /**
   * constructor.
   */
  public TimeChooser()
  {
    HorizontalPanel mainPanel = new HorizontalPanel();

    for (int i = 0; i < 24; i++) {
      String hourValue = "";
      if (i < 10) {
        hourValue += "0";
      }
      hourValue += i;
      hoursListBox.addItem(hourValue);
    }
    for (int i = 0; i < 60; i += 5) {
      String minuteValue = "";
      if (i < 10) {
        minuteValue += "0";
      }
      minuteValue += i;
      minutesListBox.addItem(minuteValue);
    }

    mainPanel.add(hoursListBox);
    mainPanel.add(new Label(":"));
    mainPanel.add(minutesListBox);
    setValue(new Date());
    hoursListBox.addChangeListener(changeListeners);
    minutesListBox.addChangeListener(changeListeners);
    mainPanel.addStyleName(CssNames.TIME_CHOOSER_CSS_STYLE);
    initWidget(mainPanel);
  }



  /**
   * returns the current value of the widget.
   * 
   * @return the current value of the widget
   */
  public Date getValue()
  {
    long time = 0;
    time += MS_BY_HOUR * hoursListBox.getSelectedIndex();
    time += MS_BY_MINUTE * 5 * minutesListBox.getSelectedIndex();
    return new Date(time);
  }



  /**
   * set the current value of the widget.
   * 
   * @param date
   *          the current value of the widget
   */
  public void setValue(final Date date)
  {
    long time = date == null ? (new Date()).getTime() : date.getTime();
    hoursListBox.setSelectedIndex((int) ((time % MS_BY_DAY) / MS_BY_HOUR));
    minutesListBox.setSelectedIndex((int) ((time % MS_BY_HOUR) / MS_BY_MINUTE) / 5);
  }
  



  /**
   * register a new {@link ChangeListener}.
   * 
   * @param listener
   *          the {@link ChangeListener} to register
   */
  public void addChangeListener(ChangeListener listener)
  {
    changeListeners.add(listener);
  }



  /**
   * remove a registered {@link ChangeListener}.
   * 
   * @param listener
   *          the {@link ChangeListener} to remove
   * @see com.google.gwt.user.client.ui.SourcesChangeEvents#removeChangeListener(com.google.gwt.user.client.ui.ChangeListener)
   */
  public void removeChangeListener(ChangeListener listener)
  {
    changeListeners.remove(listener);
  }


  /**
   * getter for the enableState property.
   * 
   * @return the enableState
   */
  public boolean isEnabled()
  {
    return hoursListBox.isEnabled();
  }



  /**
   * setter for the enableState property.
   * 
   * @param enableState
   *          the enableState to set
   */
  public void setEnabled(boolean enableState)
  {
    hoursListBox.setEnabled(enableState);
    minutesListBox.setEnabled(enableState);
  }

}
